package com.rabbitmq.ChattingRoom.controller.biz;

import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.chattingroom.mqproducer.mqproducer.feign.interfaces.MyProducerFeign;
import com.rabbitmq.ChattingRoom.config.RedisUtilTemplate;
import com.rabbitmq.ChattingRoom.service.RoomService;
import com.rabbitmq.ChattingRoom.service.UserRoomMappingService;
import com.rabbitmq.ChattingRoom.service.UserService;
import com.rabbitmq.ChattingRoom.util.Entity.Room;
import com.rabbitmq.ChattingRoom.util.Entity.User;
import com.rabbitmq.ChattingRoom.util.Entity.UserRoomMapping;
import com.rabbitmq.ChattingRoom.util.common.base.Result;
import com.rabbitmq.ChattingRoom.util.common.req.*;
import com.rabbitmq.ChattingRoom.util.common.resp.RoomRESP;
import com.rabbitmq.ChattingRoom.util.common.resp.UserRESP;
import com.rabbitmq.ChattingRoom.util.utils.BeanUtil;
import com.rabbitmq.ChattingRoom.util.utils.JSONUtil;
import com.rabbitmq.ChattingRoom.util.utils.TokenUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Component
public class RoomBiz {

    @Autowired
    private RoomService roomService;
    @Autowired
    private UserRoomMappingService userRoomMappingService;
    @Autowired
    private UserService userService;

    @Autowired
    private MyProducerFeign myProducerFeign;

    private RedisUtilTemplate redisUtilTemplate = new RedisUtilTemplate();


    public Result<String> createRoom(CreateChattingRoomReq req, String token) {
        Object userStr = redisUtilTemplate.get("user_" + TokenUtils.getId(token));
        if (ObjectUtils.isEmpty(userStr)) {
            return Result.error("当前用户已下线!");
        }
        Room room = BeanUtil.copyProperties(req, Room.class);
        Long roomId = IdWorker.getId();
        room.setId(roomId);
        // 先创建 聊天室 queue，聊天室创建成功才会在数据库插入新建聊天室信息
        boolean flag1 = myProducerFeign.createQueue(roomId.toString());
        if (!flag1) {
            return Result.error("创建失败!");
        }

        room.setRoomCreater(JSONUtil.parse(userStr.toString(), User.class).getId());
        Integer flag = roomService.addRoom(room);
        if (flag > 0) {
//            创建成功之后，将自己加入到该聊天室中
            userRoomMappingService.addUserRoomMapping(
                    new UserRoomMapping()
                            .setRoomId(roomId)
                            .setUserId(TokenUtils.getId(token))
                            .setId(IdWorker.getId())
            );
            return Result.success("创建成功!");
        }
        return Result.error("创建失败!");
    }

    public Result<String> joinRoom(UserJoinRoomReq req) {
        // 检查 userid roomid是否存在
        if (!userService.isExistId(req.getUserId())) {
            return Result.error("用户id错误!");
        }
        if (!roomService.isExistId(req.getRoomId())) {
            return Result.error("聊天室id错误!");
        }

        // 已经加入的情况
        if (userRoomMappingService.isExist(req.getUserId(), req.getRoomId())) {
            return Result.success("已存在，请勿重复添加!", null);
        }

        Integer flag = userRoomMappingService.addUserRoomMapping(BeanUtil.copyProperties(req, UserRoomMapping.class));
        if (!ObjectUtils.isEmpty(flag) && flag > 0) {
            return Result.success("加入成功!");
        }
        return Result.error("加入失败!");
    }

    public Result<String> exitRoom(UserJoinRoomReq req, String token) {
        // 检查 userid roomid是否存在
        if (!userService.isExistId(req.getUserId())) {
            return Result.error("用户id错误!");
        }
        if (!roomService.isExistId(req.getRoomId())) {
            return Result.error("聊天室id错误!");
        }

        // 获取聊天室的创建人
        Long roomCreater = roomService.getRoomCreaterByRoomId(req.getRoomId());

        // 获取当前用户id
        Long userId = TokenUtils.getId(token);

        if (!(userId.equals(roomCreater) || userId.equals(req.getUserId()))) {
            return Result.error("无权移除改用户!");
        }

        Integer flag = userRoomMappingService.delUserRoomMapping(BeanUtil.copyProperties(req, UserRoomMapping.class));
        if (!ObjectUtils.isEmpty(flag) && flag > 0) {
            // 给被移出用户发送 消息，通知该用户已被退出聊天室
            TellUserQuitChattingRoomReq reqMsg = new TellUserQuitChattingRoomReq();
            reqMsg.setUserId(req.getUserId().toString()).setNickName(userService.selectUserById(userId).getNickname());
            myProducerFeign.sendQuitMessageToQueue(reqMsg);
            return Result.success("退出成功!");
        }
        return Result.error("退出失败!");
    }

    public Result<List<RoomRESP>> listRoom(String token) {
        return Result.success("获取成功!", roomService.getRoomsByUser(TokenUtils.getId(token)));
    }

    public Result<List<RoomRESP>> rooms() {
        List<Room> rooms = roomService.getRooms(1);
        List<RoomRESP> roomRESPS = new ArrayList<>();
        for (Room room : rooms) {
            roomRESPS.add(BeanUtil.copyProperties(room, RoomRESP.class));
        }
        return Result.success("获取成功!", roomRESPS);
    }

    @Transactional
    public Result<String> del(RoomDelReq req, String token) {
        // 根据token获取用户id
        Long userId = TokenUtils.getId(token);
        Room record = new Room()
                .setId(req.getRoomId())
                .setRoomCreater(userId);
        // 删除当前聊天室 queue
        if (myProducerFeign.deleteByQueueName(req.getRoomId().toString())) {
            roomService.delRoomByUser(record);
            userRoomMappingService.delInfoByRoom(req.getRoomId());
            return Result.success("删除成功!");
        }
        return Result.error("删除失败!");
    }

    public Result<List<HistoryMSGReq>> getMsgByCount(GetMsgReq req) {
        return Result.success(roomService.getMsgByCount(req));
    }

    public Result<List<UserRESP>> getUsers(Long roomId) {
        return Result.success("获取成功!", userService.getUsersByRoomId(roomId));
    }
}
